from tools import *
from job import *
import os
import sys
import time
import subprocess
import signal

LOG = getlogger(__name__)


def restart(flag=True):
    if flag:
        LOG.info('receive signal, gracefully restart....')
        args = [sys.executable] + sys.argv
        new_environ = os.environ.copy()
        new_environ['MONDO_PPID'] = str(os.getpid())
        for key, value in new_environ.iteritems():
            if isinstance(value, unicode):
                new_environ[key] = value.encode('iso-8859-1')
        p = subprocess.Popen(args, env=new_environ, close_fds=False)
        exit_code = p.wait()
        if exit_code:  # should not run
            LOG.error('subprocess error')


def shutdown(flag=True):
    if flag:
        LOG.info('receive signal, gracefully stop %d ....' % os.getpid())
        scheduler.stop()


def add_job_callback(jobobj, job):  # jobobj is tuple
    try:
        for name, value, signature in jobobj:
            LOG.info('addding new job: %s , by callback from job %s' %
                     (name, job.name))
            job = gennerate_job(name, value, signature)
            scheduler.jobs.append(job)
        return True
    except Exception, ex:
        LOG.error('add job error: %s ' % ex)
        return False


CALLBACKS['restart_on_condition'] = lambda x, y: restart(x)
CALLBACKS['force_restart'] = lambda x, y: restart(x)
CALLBACKS['add_job'] = add_job_callback
CALLBACKS['force_shutdown'] = lambda *args: shutdown()
ERR_CALLBACKS['force_restart'] = lambda *args: restart()
ERR_CALLBACKS['force_shutdown'] = lambda *args: shutdown()

jobs = validate_and_convert_jobs(DIRS, CALLBACKS, ERR_CALLBACKS,
                                 TASK_CONF_FILE)
scheduler = Scheduler(jobs)


def main():
    LOG.info('callbacks loads: %s', CALLBACKS.keys())
    LOG.info('error callbacks loads: %s', ERR_CALLBACKS.keys())
    LOG.info('mondev client start....')
    signal.signal(signal.SIGTERM, lambda *args: shutdown())
    signal.signal(signal.SIGQUIT, lambda *args: shutdown())
    signal.signal(signal.SIGINT, lambda *args: shutdown())
    signal.signal(signal.SIGUSR2, lambda *args: restart())
    ppid = os.environ.get('MONDO_PPID')
    if ppid:
        LOG.info('start as subprocess,kill ppid %s' % ppid)
        try:
            LOG.info(os.system('ps -ef|grep python'))
            os.kill(int(ppid), signal.SIGTERM)
            time.sleep(2)
            if not checkprocess('.*', None, None, ppid):
                LOG.error('process %s kill error, use kill -9' % ppid)
                os.kill(int(ppid), signal.SIGKILL)
                if not checkprocess('.*', None, None, ppid):
                    LOG.info('process %s kill again.' % ppid)
                    stop_proc(ppid, 5)
                    LOG.error('process %s kill error, quit' % ppid)
                    sys.exit(2)
        except Exception, ex:
            LOG.error('error %s while killing' % ex)
            sys.exit(2)
    daemonize()
    LOG.info('mondev client running....')
    scheduler.run()


if __name__ == "__main__":
    main()
